use biodivine_lib_param_bn::biodivine_std::traits::Set;
use biodivine_lib_param_bn::symbolic_async_graph::{GraphColoredVertices, SymbolicAsyncGraph};
use biodivine_lib_param_bn::VariableId;
pub fn reachability_step<F>(
set: &mut GraphColoredVertices,
universe: &GraphColoredVertices,
variables: &[VariableId],
step: F,
) -> bool
where
F: Fn(VariableId, &GraphColoredVertices) -> GraphColoredVertices,
{
if variables.is_empty() {
return true;
}
for var in variables.iter().rev() {
let stepped = step(*var, set).minus(set).intersect(universe);
if !stepped.is_empty() {
*set = set.union(&stepped);
return false;
}
}
true
}
pub fn reach_bwd(
graph: &SymbolicAsyncGraph,
initial: &GraphColoredVertices,
universe: &GraphColoredVertices,
variables: &[VariableId],
) -> GraphColoredVertices {
let mut set = initial.clone();
loop {
if reachability_step(&mut set, universe, variables, |v, s| graph.var_pre(v, s)) {
break;
}
}
set
}